home *** CD-ROM | disk | FTP | other *** search
- // Smoke.cpp: implementation of the Smoke class.
- //
- //////////////////////////////////////////////////////////////////////
-
- #include "Std.h"
- #include "Smoke.h"
- #include "Spark.h"
- #include "Star.h"
-
- extern Spark spark[12];
- extern Star star;
- extern float gravity;
-
- #define MAXANGLES 16384
- #define NOT_QUITE_DEAD 3
-
- inline float FastDistance2D(float x, float y)
- {
- // this function computes the distance from 0,0 to x,y with ~3.5% error
-
- // first compute the absolute value of x,y
- x = (x < 0.0f) ? -x : x;
- y = (y < 0.0f) ? -y : y;
-
- // compute the minimum of x,y
- float mn = min(x,y);
-
- // return the distance
- return(x+y-(mn*0.5f)-(mn*0.25f)+(mn*0.0625f));
-
- } // end FastDistance2D
-
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
-
- float intensity = 75000.0f;
-
- Smoke::Smoke()
- {
-
- }
-
- Smoke::~Smoke()
- {
-
- }
-
- void Smoke::Update()
- {
- static int nextParticle = 0;
- static float lastParticleTime = 0.25f;
- int i,j;
- static float old[3];
- static int firstTime = 1;
- static long frame = 0;
- float mPosX;
- float mPosY;
- float mPosZ;
- float sx = star.position[0];
- float sy = star.position[1];
- float sz = star.position[2];
-
- frame++;
-
- if (!firstTime)
- {
- // release 12 puffs every frame
- if (fTime-lastParticleTime >= 1.0f / 121.0f)
- {
- float dx,dy,dz;
- float f;
- float rsquared;
- int whichSpark = 0;
- float mag;
-
- dx = old[0] - sx;
- dy = old[1] - sy;
- dz = old[2] - sz;
- //rsquared = (dx*dx+dy*dy+dz*dz);
- mag = 5.0f;// / (float) sqrt(rsquared);
- float deltax = (dx * mag);
- float deltay = (dy * mag);
- float deltaz = (dz * mag);
- for (i=0;i<numStreams;i++)
- {
- p[nextParticle].delta[0] = deltax;
- p[nextParticle].delta[1] = deltay;
- p[nextParticle].delta[2] = deltaz;
- p[nextParticle].position[0] = sx;
- p[nextParticle].position[1] = sy;
- p[nextParticle].position[2] = sz;
- p[nextParticle].oldposition[0] = sx;
- p[nextParticle].oldposition[1] = sy;
- p[nextParticle].oldposition[2] = sz;
- float streamSpeedCoherenceFactor = max(0.0f,1.0f + RandBell(0.25f*incohesion));
- if (MouseDown)
- {
- mPosZ = sz;
- mPosX = (MouseX - sys_glWidth * 0.5f) / (sys_glWidth / mPosZ);
- mPosY = (sys_glHeight * 0.5f - MouseY) / (sys_glWidth / mPosZ);
- dx = p[nextParticle].position[0] - mPosX;
- dy = p[nextParticle].position[1] - mPosY;
- dz = p[nextParticle].position[2] - mPosZ;
- rsquared = (dx*dx+dy*dy+dz*dz);
- mag = streamSpeed * 0.05f * streamSpeedCoherenceFactor / (float) sqrt(rsquared);
- p[nextParticle].delta[0] -= (dx * mag);
- p[nextParticle].delta[1] -= (dy * mag);
- p[nextParticle].delta[2] -= (dz * mag);
- }
- dx = p[nextParticle].position[0] - spark[i].position[0];
- dy = p[nextParticle].position[1] - spark[i].position[1];
- dz = p[nextParticle].position[2] - spark[i].position[2];
- rsquared = (dx*dx+dy*dy+dz*dz);
- f = streamSpeed * streamSpeedCoherenceFactor;
- mag = f / (float) sqrt(rsquared);
- p[nextParticle].delta[0] -= (dx * mag);
- p[nextParticle].delta[1] -= (dy * mag);
- p[nextParticle].delta[2] -= (dz * mag);
- p[nextParticle].color[0] = spark[i].color[0] * (1.0f + RandBell(colorIncoherence));// + RandBell(0.25f*colorIncoherence);
- p[nextParticle].color[1] = spark[i].color[1] * (1.0f + RandBell(colorIncoherence));// + RandBell(0.25f*colorIncoherence);
- p[nextParticle].color[2] = spark[i].color[2] * (1.0f + RandBell(colorIncoherence));// + RandBell(0.25f*colorIncoherence);
- p[nextParticle].color[3] = 0.85f * (1.0f + RandBell(0.5f*colorIncoherence));// + RandBell(0.125f*colorIncoherence);
- p[nextParticle].dead = FALSE;
- p[nextParticle].time = fTime;
- p[nextParticle].animFrame = rand()&63;
- nextParticle++;
- if (nextParticle == NUMSMOKEPARTICLES)
- {
- nextParticle = 0;
- }
- }
- lastParticleTime = fTime;
- }
- }
- else
- {
- lastParticleTime = fTime;
- firstTime = 0;
- }
-
- for (i=0;i<3;i++)
- {
- old[i] = star.position[i];
- }
-
- if (MouseDown)
- {
- mPosZ = seraphDistance;
- mPosX = (MouseX - sys_glWidth * 0.5f) / (sys_glWidth / mPosZ);
- mPosY = (sys_glHeight * 0.5f - MouseY) / (sys_glWidth / mPosZ);
- }
-
- // double frameRate = ((double) dframe)/(fTime -fTimeOffset);
- double frameRateModifier = fDeltaTime * 42.5f;
- // double frameRateModifier = 42.5f / frameRate;
-
- for (i=0;i<NUMSMOKEPARTICLES;i++)
- {
- if (p[i].dead)
- {
- continue;
- }
-
- float dx,dy,dz;
- float f;
- float rsquared;
- float mag;
- float deltax = p[i].delta[0];
- float deltay = p[i].delta[1];
- float deltaz = p[i].delta[2];
-
-
- // if (MouseDown)
- // {
- // mPosZ = (p[i].position[2] + star.position[2]) * 0.5f;
- // mPosX = (MouseX - sys_glWidth * 0.5f) / (sys_glWidth / mPosZ);
- // mPosY = (sys_glHeight * 0.5f - MouseY) / (sys_glWidth / mPosZ);
- // }
-
- for (j=0;j<numStreams;j++)
- {
- dx = p[i].position[0] - spark[j].position[0];
- dy = p[i].position[1] - spark[j].position[1];
- dz = p[i].position[2] - spark[j].position[2];
- rsquared = (dx*dx+dy*dy+dz*dz);
- f = (gravity/rsquared) * frameRateModifier;
- if ((i % numStreams) == j)
- {
- // if (MouseDown)
- // {
- // f *= 1.0f + streamBias * 0.25f;
- // }
- // else
- // {
- f *= 1.0f + streamBias;
- // }
- }
-
- mag = f / (float) sqrt(rsquared);
-
- deltax -= (dx * mag);
- deltay -= (dy * mag);
- deltaz -= (dz * mag);
- }
-
- if (MouseDown)
- {
- dx = p[i].position[0] - mPosX;
- dy = p[i].position[1] - mPosY;
- dz = p[i].position[2] - mPosZ;
- rsquared = (dx*dx+dy*dy+dz*dz);
- f = (gravity/rsquared) * frameRateModifier;
- f *= (1.0f + streamBias) * 0.5f;
- mag = f / (float) sqrt(rsquared) ;
- deltax -= (dx * mag);
- deltay -= (dy * mag);
- deltaz -= (dz * mag);
- }
-
- // slow this particle down by drag
- deltax *= drag;
- deltay *= drag;
- deltaz *= drag;
-
- if ((deltax*deltax+deltay*deltay+deltaz*deltaz) >= 25000000.0f)
- {
- p[i].dead = TRUE;
- continue;
- }
-
- // update the position
- p[i].delta[0] = deltax;
- p[i].delta[1] = deltay;
- p[i].delta[2] = deltaz;
- for (j=0;j<3;j++)
- {
- p[i].oldposition[j] = p[i].position[j];
- p[i].position[j] += p[i].delta[j]*fDeltaTime;
- }
- }
- }
-
- void Smoke::Draw()
- {
- static float seraphimVertices[NUMSMOKEPARTICLES*2*4];
- static float seraphimColors[NUMSMOKEPARTICLES*4*4];
- static float seraphimTextures[NUMSMOKEPARTICLES*2*4];
- int svi = 0;
- int sci = 0;
- int sti = 0;
- int si = 0;
- float width,sx,sy;
- float u0,v0,u1,v1;
- float w,z;
- static int firstTime = 1;
- if (firstTime)
- {
- firstTime = 0;
- }
-
- static long frame = 0;
- static float lastFrameTime = 0.0f;
-
- {
- frame++;
- lastFrameTime = fTime;
- }
-
- float screenRatio = sys_glWidth / 1024.0f;
-
- width = (streamSize+2.5f*streamExpansion) * screenRatio;
-
- // glBegin(GL_QUADS);
-
- float hslash2 = sys_glHeight * 0.5f;
- float wslash2 = sys_glWidth * 0.5f;
-
- for (int i=0;i<NUMSMOKEPARTICLES;i++)
- {
- if (p[i].dead == TRUE)
- {
- continue;
- }
- float thisWidth = (streamSize+(fTime-p[i].time)*streamExpansion) * screenRatio;
- if (thisWidth >= width)
- {
- p[i].dead = TRUE;
- continue;
- }
- z = p[i].position[2];
- sx = p[i].position[0] * sys_glWidth / z + wslash2;
- sy = p[i].position[1] * sys_glWidth / z + hslash2;
- float oldz = p[i].oldposition[2];
- if (sx > sys_glWidth+50.0f || sx < -50.0f || sy > sys_glHeight+50.0f || sy < -50.0f || z < 25.0f || oldz < 25.0f)
- {
- continue;
- }
-
- w = max(1.0f,thisWidth/z);
- // if (p[i].dead == NOT_QUITE_DEAD)
- // {
- // w *= 0.25f;
- // }
- float oldx = p[i].oldposition[0];
- float oldy = p[i].oldposition[1];
- float oldscreenx = (oldx * sys_glWidth / oldz) + wslash2;
- float oldscreeny = (oldy * sys_glWidth / oldz) + hslash2;
- float dx = (sx-oldscreenx);
- float dy = (sy-oldscreeny);
-
- float d = FastDistance2D(dx, dy);
-
- float s;
- if (d)
- {
- s = w/d;
- }
- else
- {
- s = 0.0f;
- }
- float os;
- float ow = max(1.0f,thisWidth/oldz);
- if (d)
- {
- os = ow/d;
- }
- else
- {
- os = 0.0f;
- }
-
- float m = 1.0f + s;
-
- float dxs = dx*s;
- float dys = dy*s;
- float dxos = dx*os;
- float dyos = dy*os;
- float dxm = dx*m;
- float dym = dy*m;
-
- p[i].animFrame++;
- if (p[i].animFrame >= 64)
- {
- p[i].animFrame = 0;
- }
-
- u0 = (p[i].animFrame&&7) * 0.125f;
- v0 = (p[i].animFrame>>3) * 0.125f;
- u1 = u0 + 0.125f;
- v1 = v0 + 0.125f;
- u1 = u0 + 0.125f;
- v1 = v0 + 0.125f;
- float cm = (1.375f - thisWidth/width);
- if (p[i].dead == 3)
- {
- cm *= 0.125f;
- p[i].dead = TRUE;
- }
- // glColor4f(p[i].color[0]*cm,p[i].color[1]*cm,p[i].color[2]*cm,p[i].color[3]*cm);
- si++;
- float cm0 = p[i].color[0]*cm;
- float cm1 = p[i].color[1]*cm;
- float cm2 = p[i].color[2]*cm;
- float cm3 = p[i].color[3]*cm;
- seraphimColors[sci++] = cm0;
- seraphimColors[sci++] = cm1;
- seraphimColors[sci++] = cm2;
- seraphimColors[sci++] = cm3;
- seraphimColors[sci++] = cm0;
- seraphimColors[sci++] = cm1;
- seraphimColors[sci++] = cm2;
- seraphimColors[sci++] = cm3;
- seraphimColors[sci++] = cm0;
- seraphimColors[sci++] = cm1;
- seraphimColors[sci++] = cm2;
- seraphimColors[sci++] = cm3;
- seraphimColors[sci++] = cm0;
- seraphimColors[sci++] = cm1;
- seraphimColors[sci++] = cm2;
- seraphimColors[sci++] = cm3;
- // glTexCoord2f(u0,v0);
- seraphimTextures[sti++] = u0;
- seraphimTextures[sti++] = v0;
- // glVertex2f(sx+dxm-dys,sy+dym+dxs);
- seraphimVertices[svi++] = sx+dxm-dys;
- seraphimVertices[svi++] = sy+dym+dxs;
- // glTexCoord2f(u0,v1);
- seraphimTextures[sti++] = u0;
- seraphimTextures[sti++] = v1;
- // glVertex2f(sx+dxm+dys,sy+dym-dxs);
- seraphimVertices[svi++] = sx+dxm+dys;
- seraphimVertices[svi++] = sy+dym-dxs;
- // glTexCoord2f(u1,v1);
- seraphimTextures[sti++] = u1;
- seraphimTextures[sti++] = v1;
- // glVertex2f(oldscreenx-dxm+dyos,oldscreeny-dym-dxos);
- seraphimVertices[svi++] = oldscreenx-dxm+dyos;
- seraphimVertices[svi++] = oldscreeny-dym-dxos;
- // glTexCoord2f(u1,v0);
- seraphimTextures[sti++] = u1;
- seraphimTextures[sti++] = v0;
- // glVertex2f(oldscreenx-dxm-dyos,oldscreeny-dym+dxos);
- seraphimVertices[svi++] = oldscreenx-dxm-dyos;
- seraphimVertices[svi++] = oldscreeny-dym+dxos;
- }
- // glEnd();
- glColorPointer(4,GL_FLOAT,0,seraphimColors);
- glVertexPointer(2,GL_FLOAT,0,seraphimVertices);
- glTexCoordPointer(2,GL_FLOAT,0,seraphimTextures);
- glDrawArrays(GL_QUADS,0,si*4);
- }
-